package no.ntnu.idi.deid.patternmatching.search.dictionary.medicalcodes;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;


import no.ntnu.idi.deid.config.FilePaths;
import no.ntnu.idi.deid.documentunits.Token;
import no.ntnu.idi.deid.searchresultunits.CategoryTag;
import no.ntnu.idi.deid.searchresultunits.Tag;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

/*
 * *******************ICD10***********************
 * 
 * 
 * Antall klasser: 10522
 * 
 * DETTE SKAL GJØRES: 
 * Kodene kan ha punktum innimellom - FIKS!
 * searchdescription 
 * 
 */


public class ICD10_Codes {
	
	private static Map<String, String> codes;
	
	private ICD10_Codes(){
		if(codes==null){
			instantiateCodesMap(true, null);
		}
	}
	//returns description
	public static CategoryTag searchICD10Code(Token t){
		new ICD10_Codes();
		String result = codes.get(removeSpecialCharactersFromICD10Code(t.getStripped()));
		if(result!=null){
			CategoryTag tag = new CategoryTag(Tag.ICD10);
			tag.setValues(removeSpecialCharactersFromICD10Code(t.getStripped()), result);
			return tag;
		}
		return null;
	}
	
	private static String removeSpecialCharactersFromICD10Code(String code){
		return code.replaceAll("[^a-zA-Z_0-9]", "");
	}
	
	/**
	 * 
	 * @param String descrition
	 * @return Returns an arraylist with ICD-10 codes which has descriptions containing input param. 
	 */
	public static ArrayList<String> searchICD10Description(CharSequence c){
		ArrayList<String> results = new ArrayList<String>();
		if(codes==null){
			instantiateCodesMap(true, null);
		}
		Iterator<Entry<String, String>> it = codes.entrySet().iterator();
		while(it.hasNext()){
			Map.Entry<String, String> e = (Map.Entry<String, String>) it.next();
			if(e.getValue().toString().contains(c)){
				results.add(e.getKey());
			}
		}
		return results;
	}
	
	public static CategoryTag searchExactICD10Description(String str){
		if(codes==null){
			instantiateCodesMap(true, null);
		}
		Iterator<Entry<String, String>> it = codes.entrySet().iterator();
		while(it.hasNext()){
			Map.Entry<String, String> e = (Map.Entry<String, String>) it.next();
			if(e.getValue().toString().equals(str)){
				CategoryTag tag = new CategoryTag(Tag.ICD10);
				tag.setValues(e.getKey(), str);
				return tag;
			}
		}
		return null;
	}

	
	//recursive method
	private static void instantiateCodesMap(boolean first, OntClass cl){
		if(first){
			codes = new HashMap<String, String>();
			OntModel ontologyModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null );
			ontologyModel.read("file:"+FilePaths.getICD10OwlFilePath());
			ExtendedIterator<OntClass> i = ontologyModel.listHierarchyRootClasses();
			while(i.hasNext()){
//				counter++;
				OntClass test = (OntClass) i.next();
				if(test.getLocalName()!=null && test.getLabel(null)!= null){
					codes.put(test.getLocalName(),test.getLabel(null));
				}
				instantiateCodesMap(false,test);
			}
		}
		else{
			ExtendedIterator<OntClass> it = cl.listSubClasses();
			while(it.hasNext()){
//				counter++;
				OntClass test = (OntClass) it.next();
				if(test.getLocalName()!=null && test.getLabel(null)!= null){
					codes.put(test.getLocalName(),test.getLabel(null));
				}
				instantiateCodesMap(false, test);
			}
		}
	}
	
	public static void main(String[] args) {
		System.out.println(searchICD10Code(new Token(5858585, "Z625")).getDescription());
	}
	
}
